﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using mvcPractice.Models;
using mvcPractice.Entity;

namespace mvcPractice.Service
{
    public class TransferService
    {
        public readonly DataDbContext _context;

        public TransferService(DataDbContext context)
        {
            _context = context;
        }

        // Get station by stationId
        public Object GetStation(int stationId)
        {
            var station = _context.AutoStation.Find(stationId);
            return station;
        }
        // Add station to database (AutoStation)
        public void AddStation(AutoStation station)
        {
            _context.AutoStation.Add(station);
            _context.SaveChanges();
        }
        // Update station information to database (AutoStation)
        public AutoStation UpdateStation(AutoStation station)
        {
            var oldStation = (AutoStation)this.GetStation(station.Id);
            oldStation.Name = station.Name;
            oldStation.PortName = station.PortName;

            _context.SaveChanges();
            return oldStation;
        }
        // Delete station
        public void DelStation(int stationId)
        {
            var station = _context.AutoStation.Find(stationId);
            _context.AutoStation.Remove(station);
            _context.SaveChanges();
        }

        //linq test
        public void linqtest()
        {
            var query = from s in _context.AutoStation
                        join r in _context.AutoHydroLevelRawResult on s.Id equals r.StationId
                        // 联合两个集合中的成员生成一个新的集合
                        // 结果是把两个集合成员具有相同StationId的拿出来组成一个新的集合
                        where r.Value > 30
                        // 找出新集合中符合条件的成员
                        select r;
            // 此处的query并不真正的去执行查询，如果query返回一个枚举，查询会在处理枚举时执行
            // 如在下面的foreach中进行查询
            foreach (var r in query)
                Console.WriteLine("stationID为：{0},value：{1},projectId:{2}", r.StationId, r.Value, r.Id);

            /// from... let... 在from查询语句中可以利用let引入新的数据源
            var arrA = new[] { 1, 2, 3 };
            var arrB = new[] { 3, 4, 5 };
            var sumAB = (from a in arrA
                         from b in arrB
                         let sum = a + b
                         where sum > 4
                         select new { a, b, sum }).ToList();
            Console.WriteLine(sumAB);

            /// select... group... by... 分组
            var result1 = from r in _context.AutoHydroLevelRawResult
                          where r.Number < 1250
                          group r by r.Number;
            //result1 返回的是IEumerable<IGrouping<键，值>>，所以不能直接打印。用r.key分组键分别打印。
            foreach (var r in result1)
            {
                Console.WriteLine("{0}", r.Key);
                foreach (var x in r)
                    Console.WriteLine("{0},{1},{2}", x.Id, x.Value, x.Number);
            }

            /// into 将查询的一部分结果命名成新的名字，可用于其他查询
            var result2 = from r in _context.AutoHydroLevelRawResult
                          where r.Number < 1235
                          group r by r.Number into NumberList
                          from n in NumberList
                          group n by n.PointName;
            foreach (var r in result2)
            {
                Console.WriteLine($"groupBy number where number<1235,number = {r.Key}");
                foreach (var n in r)
                    Console.WriteLine("{0},{1},{2}", n.PointName, n.Number, n.Id);
            }

            /// groupby let orderby mix
            var result3 = from r in _context.AutoHydroLevelRawResult
                          where r.Number < 1230 && r.Value > 20
                          group r by r.PointName into NewList
                          from x in NewList
                          let first = NewList.First()
                          orderby x.PointName, x.Number ascending
                          select new
                          {
                              DateTime = first.DateTime,
                              ProjectId = x.Id,
                              Value = x.Value,
                              Number = x.Number,
                              PointName = x.PointName
                          };
            foreach (var r in result3)
                Console.WriteLine("{0},{1},{2}", r.DateTime, r.PointName, r.Value);

            /// 方法语法使用
            var result4 = (from r in _context.AutoHydroLevelRawResult
                           where r.Number < 1240
                           select r.Value).Average();
            Console.WriteLine("The average that result's number less than 1240 is:{0}", result4);

            /// selectMany 映射
            var result5 = _context.AutoHydroLevelRawResult.Where(r => r.Number < 1232 && r.Value > 20)
                            .GroupBy(r => r.PointName).Select(g => g.Key).OrderBy(x => x).ToList();
            Console.WriteLine(result5);
            //result5 结果为分组后的key 用selectmany来代替foreach来做映射
            string MapFun(string x)
            {
                return "PointName:" + x;
            }
            string[] FlatMapFun(string x, int index)
            {
                var s = "PointName:" + x + " index:" + index;
                return new string[] { s, s };
            }
            var result6 = result5.Select(x => MapFun(x));
            foreach (var r in result6)
                Console.WriteLine("映射后的结果{0}", r);
            var result7 = result5.SelectMany((x, index) => FlatMapFun(x, index));
            foreach (var r in result7)
                Console.WriteLine("flat映射后的结果{0}", r);
        }
    }
}
